using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using AvaloniaApplication1.Models;
using Modbus.Device;
using MQTTnet.Protocol;

namespace AvaloniaApplication1.IServices;

public interface IModbusManager
{
    /// <summary>
    /// 添加Modbus设备
    /// </summary>
    Task<bool> AddModbusDeviceAsync(ModbusConfig modbusConfigModel);
    
    /// <summary>
    /// 移除Modbus设备
    /// </summary>
    /// <param name="deviceName">设备名称</param>
    /// <returns></returns>
    Task<bool> RemoveModbusDeviceAsync(string deviceName);

    /// <summary>
    /// 连接Modbus设备
    /// </summary>
    /// <param name="deviceName">设备名称</param>
    /// <returns></returns>
    Task<bool> ConnectModbusDeviceAsync(string deviceName,string tcpName);

    /// <summary>
    /// 断开Modbus设备
    /// </summary>
    /// <param name="deviceName">设备名称</param>
    /// <returns></returns>
    Task<bool> DisconnectModbusDeviceAsync(string deviceName);

    /// <summary>
    /// 读取保持寄存器
    /// </summary>
    /// <param name="deviceName">设备名称</param>
    /// <returns>寄存器值数组</returns>
    Task<ushort[]> ReadHoldingRegistersAsync(string deviceName);
    /// <summary>
    /// 从站配置
    /// </summary>
    /// <param name="deviceName">设备名称</param>
    /// <param name="slaveId">从站地址</param>
    /// <param name="slaveStartAddress">起始地址</param>
    /// <param name="slaveCount">读取数量</param>
    /// <returns></returns>
    Task<bool> SlaveConfigureDeviceAsync(string deviceName,byte slaveId,ushort slaveStartAddress, ushort slaveCount,int intervalTime);
    
    Task<bool> ConfigureDeviceAsync(string deviceName,string serverip,string tcpname,Dictionary<string, int> ports,int timeout );

    /// <summary>
    /// 写入单个保持寄存器
    /// </summary>
    /// <param name="deviceName">设备名称</param>
    /// <param name="slaveId">从站地址</param>
    /// <param name="writeRegisterAddress">起始地址</param>
    /// <param name="value">要写入的值</param>
    /// <returns>操作结果</returns>
    Task<bool> WriteSingleHoldingRegistersAsync(string deviceName,byte slaveId,ushort writeRegisterAddress, ushort value);

    /// <summary>
    /// 写入多个保持寄存器
    /// </summary>
    /// <param name="deviceName">设备名称</param>
    /// <param name="slaveId">从站地址</param>
    /// <param name="writeRegisterAddress">起始地址</param>
    /// <param name="values">要写入的值数组</param>
    /// <returns></returns>
    Task<bool> WriteMultipleHoldingRegistersAsync(string deviceName,byte slaveId,ushort writeRegisterAddress, ushort[] values);

    
    /// <summary>
    /// 获取设备信息
    /// </summary>
    ModbusConfig? GetModbusDevice(string deviceName);

    /// <summary>
    /// 获取所有设备
    /// </summary>
    Task<IEnumerable<ModbusConfig>> GetAllModbusDevices();

    /// <summary>
    /// 检查端口是否存在
    /// </summary>
    Task<bool> CheckPortExistsAsync(string deviceName, string tcpName);
    /// <summary>
    /// 判断modbus设备是否存在
    /// </summary>
    /// <param name="deviceName"></param>
    /// <returns></returns>
    bool ContainsModbusDevice(string deviceName);


    /// <summary>
    /// 设备状态变更事件
    /// </summary>
    event EventHandler<ModbusDeviceStatusEventArgs> ModbusDeviceStatusChanged;

    /// <summary>
    /// 设备数据接收事件
    /// </summary>
    event EventHandler<DeviceDataEventArgs> ModbusDeviceDataReceived;
    /// <summary>
    /// 设备添加事件
    /// </summary>
    event EventHandler<ModbusDeviceEventArgs> ModbusDeviceAdded;
    /// <summary>
    /// 设备移除事件
    /// </summary>
    event EventHandler<ModbusDeviceEventArgs> ModbusDeviceRemoved;
}

public class ModbusDeviceEventArgs : EventArgs
{
    public ModbusConfig ModbusConfig;
   
    public ModbusDeviceEventArgs(ModbusConfig modbusConfig)
    {
        ModbusConfig=modbusConfig;
     
    }
}

/// <summary>
/// 设备状态事件参数
/// </summary>
public class ModbusDeviceStatusEventArgs : EventArgs
{
    public string DeviceName { get; }
    public bool IsConnected { get; }

    public ModbusDeviceStatusEventArgs(string deviceName, bool isConnected)
    {
        DeviceName = deviceName;
        IsConnected = isConnected;
    }
}

/// <summary>
/// 设备数据事件参数
/// </summary>
public class ModbusDeviceDataEventArgs : EventArgs
{
    public string DeviceName { get; }
    public string Payload { get; }

    public ModbusDeviceDataEventArgs(string deviceName, string payload)
    {
        DeviceName = deviceName;
        Payload = payload;
    }
}